-- la idea es filtrar las citas que tienen la misma fecha, en caso de que no hayan citas con misma fecha se retorna la lista vacio, caso contrario -- luego con esta lista se evalua cuales tienen horas superpuestas, si ho hay horas que se superpongan se retorna vacio
-- una vez que obtengo la lista con las citas con horas superpuestas, busco cual tiene mayor prioridad y retorno el de maxima prioridad.

import Data.List
fst4 :: (String,String,String,Int) -> String
fst4 (x,y,z,w) = x

snd4 :: (String,String,String,Int) -> String
snd4 (x,y,z,w) = y

thd4 :: (String,String,String,Int) -> String
thd4 (x,y,z,w) = z

cth4 :: (String,String,String,Int) -> Int
cth4 (x,y,z,w) = w




-- La funcion controlPrioridad lo que hace es tomar la lista que retorna la funcion filtrarCitasMismahora y controla el parametro prioridad para
-- ver cual es el mayor y asi retornar la cita con mayor prioridad para que forme parte del subconjunto de citas de maxima prioridad 

controlPrioridad :: [(String,String,String,Int)] -> (String,String,String,Int)
controlPrioridad (x:xs) = maxPrior x xs


maxPrior :: (String,String,String,Int) -> [(String,String,String,Int)] -> (String,String,String,Int)
maxPrior x [] = x
maxPrior x (y:xs) | (cth4 x < cth4 y) = maxPrior y xs
				  | otherwise = maxPrior x xs

-- La funcion que toma las citas con misma fecha y evalua de esa lista las que tienen horas superpuestas retornando solo la cita de mayor prioridad


citasArealizar :: [(String,String,String,Int)] -> [(String,String,String,Int)]
citasArealizar (x:xs) = citasNoSuperpuestas (citasHora (x:xs))


citasNoSuperpuestas :: [(String,String,String,Int)] -> [(String,String,String,Int)]
citasNoSuperpuestas [] = []
citasNoSuperpuestas (x:xs) = controlPrioridad zs : citasNoSuperpuestas ys
						where
						zs = filtrarCitasMismaFecha (x:xs)
						ys = (x:xs) \\ zs



-- La funcion filtrarCitasMismaFecha es la encargada de retornar la lista de citas que tienen el mismo dia


filtrarCitasMismaFecha ::   [(String,String,String,Int)] -> [(String,String,String,Int)]
filtrarCitasMismaFecha [] = []
filtrarCitasMismaFecha (m:ms) |length (filter fechas (m:ms)) <=  1 = []  
							  |otherwise = filter fechas (m:ms)
								where
								fechas z = (fst4 z == fst4 m)  
	

-- La funcion filtrarCitasMismaHora es la encargada de retornar el subconjunto de citas que se superponen

filtrarCitasMismaHora :: [(String,String,String,Int)] -> [(String,String,String,Int)]
filtrarCitasMismaHora [] = []
filtrarCitasMismaHora (m:xs) =  filter hora (m:xs)
							where
							hora z = (snd4 z == snd4 m)  || ((snd4 z > snd4 m)  && ((snd4 z <= thd4 m) && (thd4 m <= thd4 z))) || ((snd4 z < snd4 m) && ((thd4 z <= thd4 m) && (thd4 z >= snd4 m))) 



-- La funcion citasFecha retorna la lista con las citas que tienen la misma fecha

citasFecha :: [(String,String,String,Int)] -> [(String,String,String,Int)]
citasFecha [] = []
citasFecha (x:xs) | zs == [] = []
				  | otherwise = zs ++ citasFecha ys
					where
					 zs = filtrarCitasMismaFecha (x:xs)
					 ys = (x:xs) \\ zs 
					 
-- la funcion citasHora  utiliza la funcion citasFecha para obtener las citas con las mismas fechas y luego le aplica a la lista resultante la 
-- funcion filtrarCitasMismaFecha para tener la lista con las citas con la misma fecha, luego llammo a la funcion filtrarCitasMismaHora para
-- obtener las citas que se superponen
-- ejemplo:
-- citasFecha [("12/4","08:00","12:00",5),("13/4","05:00","07:00",10),("12/4","07:00","10:00",8),("13/4","03:00","06:00",5),
-- ("18/4","09:00","12:00",7),("13/4","08:00","09:00",12),("12/4","14:00","18:00",7)])
-- [("12/4","08:00","12:00",5),("13/4","05:00","07:00",10),("12/4","07:00","10:00",8),("13/4","03:00","06:00",5),
-- ("13/4","08:00","09:00",12),("12/4","14:00","18:00",7)])
-- filtrarCitasMismaFecha [("12/4","08:00","12:00",5),("13/4","05:00","07:00",10),("12/4","07:00","10:00",8),("13/4","03:00","06:00",5),
-- ("13/4","08:00","09:00",12),("12/4","14:00","18:00",7)])
-- [("12/4","08:00","12:00",5),("12/4","07:00","10:00",8),("12/4","14:00","18:00",7)]
-- filtrarCitasMismaFecha [("12/4","08:00","12:00",5),("12/4","07:00","10:00",8),("12/4","14:00","18:00",7)]
-- [("12/4","08:00","12:00",5),("12/4","07:00","10:00",8)]

citasHora :: [(String,String,String,Int)] -> [(String,String,String,Int)]
citasHora [] = []
citasHora [_] = []
citasHora xs | zs == [] = []
			 |otherwise =  zs ++ citasHora ys

					where
					ws = filtrarCitasMismaFecha (citasFecha xs)
					zs = filtrarCitasMismaHora ws 
					ys = xs \\ zs


					

subconjuntoCitas :: [(String,String,String,Int)] -> [(String,String,String,Int)]
subconjuntoCitas (x:xs) | ys == [] = (x:xs)
						| otherwise  = nub(zs ++ ws ++ ts)
							where
							zs = citasArealizar (x:xs) -- zs = cita de maxima prioridad dentro de la lista de citas superpuestas  
							ys = citasFecha (x:xs)     -- ys = lista de citas con misma fecha
							vs = citasHora(x:xs)	   -- vs = lista de citas con misma fecha y horas inicio y fin superpuestas	
							ts = (x:xs) \\ vs          -- ts = lista que resulta de quitarle a la lista de citas original la lista de citas 
							ws = (x:xs) \\ ys          -- con misma fecha y horas inicio y fin superpuestas
												       -- ws = lista que resulta de quitarle a la lita de citas original la lista de citas	
                                                       --  con misma fecha


-- casos de prueba
--lista de citas con misma fecha y algunas citas con horas superpuetas:
-- subconjuntoCitas [("12/4","08:00","12:00",5),("12/4","05:00","07:00",10),("12/4","07:00","10:00",8),("12/4","03:00","06:00",5),----   ("12/4","09:00","12:00",17),("12/4","22:00","23:00",12),("12/4","10:00","13:00",7)]


-- lista de citas con misma fecha y todas las fechas superpuestas:
-- subconjuntoCitas [("12/4","08:00","12:00",5),("12/4","05:00","07:00",10),("12/4","07:00","10:00",8),("12/4","03:00","06:00",5),("12/4","09:00","12:00",17),("12/4","22:00","23:00",12),("12/4","10:00","13:00",7)]

-- lista de citas con fechas diferentes:
-- subconjuntoCitas [("07/4","08:00","12:00",5),("09/4","05:00","07:00",10),("10/4","07:00","10:00",8),("12/4","03:00","06:00",5),("11/4","09:00","12:00",17),("13/4","22:00","23:00",12),("14/4","13:00","15:00",7)]


-- lista con algunas fechas superpuestas: 
-- subconjuntoCitas [("12/4","08:00","12:00",5),("13/4","05:00","07:00",10),("12/4","07:00","10:00",8),("13/4","03:00","06:00",5),("18/4","09:00","12:00",7),("13/4","08:00","09:00",12),("12/4","13:00","15:00",7)]

